package com.asa.tongji.fenxi;

import java.awt.List;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;

import com.asa.hutils.MathHUtils;
import com.asa.tongji.TUtils1;
import com.asa.tongji.bean.ZhuChengFenFenxiBaogao;
import com.asa.utils.Calculate;

/**
 * 主成分分析
 * @author Administrator
 *
 */
public class ChengFenFenXi {

	public static ZhuChengFenFenxiBaogao chafen(double[][] x) throws Exception{
		
		double[] averages = new double[x.length];
		for (int i = 0; i < averages.length; i++) {
			averages[i] = TUtils1.average(x[i]);
		}
		double[] variances = new double[x.length];
		for (int i = 0; i < variances.length; i++) {
			variances[i] = TUtils1.standardDeviation_chafen(x[i]);
		}
		double[][] xu = new double[x.length][x[0].length];
		for (int i = 0; i < xu.length; i++) {
			for (int j = 0; j < xu[i].length; j++) {
				xu[i][j] = (x[i][j]-averages[i])/variances[i];
			}
		}
		for (int i = 0; i < xu.length; i++) {
			for (int j = 0; j < xu[i].length; j++) {
				System.out.print(xu[i][j]+"\t");
			}
			//System.out.println();
		}
		
		
		int xiangguanxishu[][] = cixu(x.length);
		for (int i = 0; i < xiangguanxishu.length; i++) {
			//System.out.println(Arrays.toString(xiangguanxishu[i]));
		}
		double asa[] = new double[xiangguanxishu.length];
		for (int i = 0; i < xiangguanxishu.length; i++) {
			asa[i] = TUtils1.correlationCoefficient(xu[xiangguanxishu[i][0]], xu[xiangguanxishu[i][1]]);
		}
		
		//System.out.println(Arrays.toString(asa));
		double[][] A = new double[x.length][x.length];
		for (int i = 0; i < A.length; i++) {
			A[i][i] = 1;
		}
		for (int i = 0; i < xiangguanxishu.length; i++) {
			BigDecimal bd = new BigDecimal(asa[i]);  
	        bd = bd.setScale(2, RoundingMode.HALF_UP);
			A[xiangguanxishu[i][0]][xiangguanxishu[i][1]] = Double.parseDouble(bd.toString());
			A[xiangguanxishu[i][1]][xiangguanxishu[i][0]] = Double.parseDouble(bd.toString());
		}
		
		for (int i = 0; i < A.length; i++) {
			for (int j = 0; j < A[i].length; j++) {
				System.out.print(A[i][j]+"\t");
			}
			//System.out.println();
		}
//		double[][] data = {{1,0.19,0.36},{0.19,1,0.30},{0.36,0.3,1}};
		double[] juzhengtezhengzhi = MathHUtils.juzhengtezhengzhi(A);
		double[][] juzhengtezhengxiangliang = MathHUtils.juzhengtezhengxiangliang(A);
		//System.out.println("==============特征向量=================");
		
		for (int i = 0; i < juzhengtezhengzhi.length; i++) {
			System.out.print(juzhengtezhengzhi[i]+"\t");
		}
		//System.out.println();
		
		for (int i = 0; i < juzhengtezhengxiangliang.length; i++) {
			for (int j = 0; j < juzhengtezhengxiangliang.length; j++) {
				System.out.print(juzhengtezhengxiangliang[i][j]+"\t");
			}
			//System.out.println();
		}
		
		//System.out.println("*************特征向量输出完毕********************");
		double xu2[][] = new double[xu[0].length][xu.length];
		for (int i = 0; i < xu.length; i++) {
			for (int j = 0; j < xu[i].length; j++) {
				xu2[j][i] = xu[i][j];
			}
		}
		
		//System.out.println(xu2.length);
		double[][] dinzhuchengfen = new double[juzhengtezhengxiangliang.length][xu2.length];
		for (int i = 0; i < juzhengtezhengxiangliang.length; i++) {
			for (int j = 0; j < xu2.length; j++) {
				
//				//System.out.println(Arrays.toString(xu2[j]));  2
				dinzhuchengfen[i][j] = func(xu2[j],juzhengtezhengxiangliang[i]);
				System.out.print(func(xu2[j],juzhengtezhengxiangliang[i])+"\t");
			}
			//System.out.println();
		}
		
		int[] getmaxindex = getmaxindex(juzhengtezhengzhi);
		//System.out.println(getmaxindex);
		
		
		
		
		
		ZhuChengFenFenxiBaogao baogao = new ZhuChengFenFenxiBaogao();
		baogao.setYuanshuju(x);
		baogao.setBiaoliangbiaozhuhua(xu);
		baogao.setXiangguanjuzheng(A);
		baogao.setTeizhengxiangliang(juzhengtezhengxiangliang);
		baogao.setTeizhengzhi(juzhengtezhengzhi);
		baogao.setZhuchengfenindex(getmaxindex);
		baogao.setDinzhuchengfen(dinzhuchengfen);
		double zhuchenfenzhangbi= 0;//精度分析,第一主成分和第二主成分占比和最好大于50%
		double all=0;
		
		for (int i = 0; i < juzhengtezhengzhi.length; i++) {
			all+=juzhengtezhengzhi[i];
		}
		//System.out.println(Arrays.toString(getmaxindex));
		//System.out.println(all);
		//System.out.println((juzhengtezhengzhi[getmaxindex[0]]+juzhengtezhengzhi[getmaxindex[1]]));
		zhuchenfenzhangbi = (juzhengtezhengzhi[getmaxindex[0]]+juzhengtezhengzhi[getmaxindex[1]])/all;
		//System.out.println(zhuchenfenzhangbi);
		baogao.setZhanbi(zhuchenfenzhangbi);
		return baogao;
	}
	
	private static int[] getmaxindex(double []x){
		int index = 0;
		double xx = x[index];
		int[] n = new int[2];
		for (int i = 0; i < x.length; i++) {
			if (x[i]>xx) {
				xx = x[i];
				n[0] = i;
			}

		}
		for (int i = 0; i < x.length; i++) {
			if (i!=n[0]) {
				xx = x[i];
				break;
			}
		}
		for (int i = 0; i < x.length; i++) {
			if (x[i]>=xx&&n[0]!=i) {
				xx = x[i];
				n[1] = 1;
				//System.out.println(".....................................................................................");

			}
		}
		
		
		
		return n;
	}
	
//	private static int getmaxindex(int []x){
//		
//		return 0;
//	}
	
	
	private static double func(double[] a,double[] u){
		double sum = 0;
		for (int i = 0; i < u.length; i++) {
			sum += a[i]*u[i];
		}
		return sum;
	}
	
	private static int[][] cixu(int x){
		int zuhe = (int)Calculate.zuhe(x, 2);//计算有多少种组合方式
		//System.out.println(zuhe);
		int[][] asa = new int[zuhe][2]; 
		int k = 0;
		for (int i = 0; i < x-1; i++) {
			for (int j = i+1; j < x; j++) {
				asa[k][0] = i;
				asa[k][1] = j;
				k++;
			}
		}
		return asa;
	}
	
	
	
	
	
	public static void main(String[] args) throws Exception {
		 double a[] = {2,1,5,2,3,4,4,1,3,5};
		 double b[] = {4,5,3,2,5,3,4,2,3,5};
		 double c[] = {5,1,4,3,5,2,3,1,2,3};
		 
		 double x[][] = new double[3][10];
		 x[0] = a;
		 x[1] = b;
		 x[2] = c;
		 ZhuChengFenFenxiBaogao chafen = chafen(x);
		 //System.out.println(chafen);
		 
	}
	
	
	
}
